package com.bwie.rent.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.bwie.rent.util.PageUtil;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.common.utils.PageUtils;
import com.bwie.common.utils.Query;

import com.bwie.rent.dao.HouseRentDao;
import com.bwie.rent.entity.HouseRentEntity;
import com.bwie.rent.service.HouseRentService;


@Service("houseRentService")
@SuppressWarnings("all")
public class HouseRentServiceImpl extends ServiceImpl<HouseRentDao, HouseRentEntity> implements HouseRentService {
    @Autowired
    private RestHighLevelClient client;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<HouseRentEntity> page = this.page(
                new Query<HouseRentEntity>().getPage(params),
                new QueryWrapper<HouseRentEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils eslist(Map<String, Object> params) throws IOException {
        //构建查询条件
        SearchRequest searchRequest = new SearchRequest("rent");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //构建bool查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //模糊名称查询
        if (params.get("houseName")!=null && !"".equals(params.get("houseName"))) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("houseName",params.get("houseName")));
        }
        //分页查询
        Integer page = Integer.valueOf((String) params.get("page"));
        Integer size = Integer.valueOf((String) params.get("limit"));
        searchSourceBuilder.from((page-1)*size);
        searchSourceBuilder.size(size);
        //高亮显示
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        HighlightBuilder.Field highlightTitle =
                new HighlightBuilder.Field("houseName");
        highlightTitle.highlighterType("unified");
        highlightBuilder.field(highlightTitle);
        highlightBuilder.preTags("<b><span style='color:red'>");
        highlightBuilder.postTags("</span></b>");

        searchSourceBuilder.highlighter(highlightBuilder);
        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);

        //执行查询条件
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        //处理查询结果
        SearchHits hits = searchResponse.getHits();
        TotalHits totalHits = hits.getTotalHits();
// the total number of hits, must be interpreted in the context of totalHits.relation
        long numHits = totalHits.value;
// whether the number of hits is accurate (EQUAL_TO) or a lower bound of the total (GREATER_THAN_OR_EQUAL_TO)
        TotalHits.Relation relation = totalHits.relation;
        float maxScore = hits.getMaxScore();
        //创建一个数组
        ArrayList<HouseRentEntity> list = new ArrayList<>();

        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            // do something with the SearchHit
            String index = hit.getIndex();
            String id = hit.getId();
            float score = hit.getScore();
            String sourceAsString = hit.getSourceAsString();
            HouseRentEntity houseRentEntity = JSONObject.parseObject(sourceAsString, new TypeReference<HouseRentEntity>() {
            });
            houseRentEntity.setHouseId(Integer.valueOf(id));
            //处理高亮
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField highlight = highlightFields.get("houseName");
            if (highlight!=null) {
                Text[] fragments = highlight.fragments();
                String fragmentString = fragments[0].string();
                houseRentEntity.setHouseName(fragmentString);
            }
            list.add(houseRentEntity);
        }
        //int page, int size, long total, List<T> rows
        //List<?> list, int totalCount, int pageSize, int currPage
        return new PageUtils(list,(int) numHits,page,size);
    }


}